<?php
namespace app\api\service;
use think\Controller;

/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/5/26 0026
 * Time: 15:40
 */

class NoteCode extends Controller {

    /**
     * 发送短信
     * @param $param
     * @return array
     */
    public static function send_code($param) {
        try {
            $TemplateCodeArray = ['SMS_83570002'];
            $TemplateCode = $TemplateCodeArray[$param['template_code']];

//            $target = "https://sms.aliyuncs.com/?";  // 短信接口网关
            $target = "http://dysmsapi.aliyuncs.com/?";  // 短信接口网关

            $code = rand(1000, 9999); // 生成验证码
            $mobile = $param['mobile'];//接收用户填写的手机号

            // 注意使用GMT时间
            date_default_timezone_set("GMT");
            // ISO8601规范
            $dateTimeFormat = 'Y-m-d\TH:i:s\Z';
            // 这里填写您的Access Key ID
            $accessKeyId = 'LTAI4JFTraQjomTV';
            // 这里填写您的Access Key Secret
            $accessKeySecret = 'jXR9FpGrrnJt08YHdnzaOmhDiG2Nj8';
            // 模板替换参数 eg： 尊敬的{$name},欢迎使用XXX。 $name 的替换参数就是 {"name":"张三"} 这样的写法
            $ParamString="{\"code\":\"$code\"}";
            // 公共参数
            $data = array(
                // 签名
                'SignName'          =>'就行天下',
                // 返回格式
                'Format'            => 'XML',
                // 版本号
//                'Version'           => '2016-09-27',
                'Version'           => '2017-05-25',
                // ID
                'AccessKeyId'       => $accessKeyId,
                // 签名版本
                'SignatureVersion'  => '1.0',
                // 加密方式
                'SignatureMethod'   => 'HMAC-SHA1',
                // 随机数
                'SignatureNonce'    => uniqid(),
                // 时间
                'Timestamp'         => date($dateTimeFormat),
                // 接口参数
//                'Action'            => 'SingleSendSms',
                'Action'            => 'SendSms',
                // 模板代码
                'TemplateCode'      => $TemplateCode,
                // 接受手机号
//                'RecNum'            => $mobile,
                'PhoneNumbers'            => $mobile,
                // 替换参数
//                'ParamString'       => $ParamString
                'TemplateParam'       => $ParamString
            );

            // 计算签名并把签名结果加入请求参数
            $data['Signature'] = self::computeSignature($data, $accessKeySecret);

            // 发送请求
            $result = self::https_request($target.http_build_query($data));

            $result = self::xml_to_array($result);
            if (isset($result['Error'])) {
                model('error_log')->save(['msg' => '短信发送失败:' . json_encode($result)]);
                throw new \Exception('发送失败！');
            }

            // 发送成功  添加记录
            model('note_code')->save(['code' => $code, 'mobile' => $param['mobile']]);

            return api_return(200, $result);
        } catch (\Exception $e) {
            return api_return(0, [], $e->getMessage());
        }
    }

    /**
     * CURL请求
     * @param $url
     * @return mixed|string
     */
    protected static function https_request($url)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $data = curl_exec($curl);
        if (curl_errno($curl)) {return 'ERROR '.curl_error($curl);}
        curl_close($curl);
        return $data;
    }

    /**
     * xml数据转换成数组
     * @param $xml
     * @return mixed
     */
    protected static function xml_to_array($xml)
    {
        $reg = "/<(\w+)[^>]*>([\\x00-\\xFF]*)<\\/\\1>/";
        if(preg_match_all($reg, $xml, $matches)){
            $count = count($matches[0]);
            for($i = 0; $i < $count; $i++){
                $subxml= $matches[2][$i];
                $key = $matches[1][$i];
                if(preg_match( $reg, $subxml )){
                    $arr[$key] = self::xml_to_array( $subxml );
                }else{
                    $arr[$key] = $subxml;
                }
            }
        }
        return @$arr;
    }

    /**
     * 签名
     * @param $parameters
     * @param $accessKeySecret
     * @return string
     */
    protected static function computeSignature($parameters, $accessKeySecret)
    {
        // 将参数Key按字典顺序排序
        ksort($parameters);
        // 生成规范化请求字符串
        $canonicalizedQueryString = '';
        foreach($parameters as $key => $value)
        {
            $canonicalizedQueryString .= '&' . self::percentEncode($key) . '=' . self::percentEncode($value);
        }
        // 生成用于计算签名的字符串 stringToSign
        $stringToSign = 'GET&%2F&' . self::percentEncode(substr($canonicalizedQueryString, 1));
        //echo "<br>".$stringToSign."<br>";
        // 计算签名，注意accessKeySecret后面要加上字符'&'
        $signature = base64_encode(hash_hmac('sha1', $stringToSign, $accessKeySecret . '&', true));
        return $signature;
    }

    /**
     * 处理编码
     * @param $str
     * @return mixed|string
     */
    protected static function percentEncode($str)
    {
        // 使用urlencode编码后，将"+","*","%7E"做替换即满足ECS API规定的编码规范
        $res = urlencode($str);
        $res = preg_replace('/\+/', '%20', $res);
        $res = preg_replace('/\*/', '%2A', $res);
        $res = preg_replace('/%7E/', '~', $res);
        return $res;
    }
}